package com.imessage.service.impl;

import com.bean.*;
import com.dd.plist.NSDictionary;
import com.dd.plist.PropertyListParser;
import com.imessage.comm.Constants;
import com.imessage.service.*;
import com.imessage.type.*;
import com.imessage.utils.ByteUtil;
import com.imessage.utils.StrUtil;
import com.imessage.utils.ZipUtils;
import com.imessage.web.Pages;
import io.ebean.Expr;
import io.ebean.Expression;
import io.ebean.Query;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import java.io.File;
import java.sql.Struct;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Slf4j
@Service
public class TaskServiceImpl implements TaskService {

    @Autowired
    private BaseService baseService;
    @Autowired
    private PhoneService phoneService;
    @Autowired
    private ConfigService configService;
    @Autowired
    private WumaService wumaService;
    @Autowired
    private AppleService appleService;
    @Autowired
    protected Environment environment;


    @Override
    public BusinessTaskDetail getNeedTaskBusinessTaskDetail() {
        List<Expression> expressionList=new ArrayList<Expression>();
        expressionList.add(Expr.eq("state", BusinessTaskState.wait.getCode()));
        expressionList.add(Expr.eq("BusinessTask.state",  BusinessTaskState.wait.getCode()));
        return baseService.findObject(BusinessTaskDetail.class, expressionList);
    }

    @Override
    public BusinessTaskDetail getNewBusinessTaskDetail(
            BusinessTaskCmd nextBusinessTaskCmd, DeviceVirtual deviceVirtual) {
        BusinessTask businessTask=getBusinessTask(BusinessTaskState.run);
        baseService.saveObject(businessTask);
        BusinessTaskDetail businessTaskDetail=getBusinessTaskDetail(
                businessTask,nextBusinessTaskCmd, deviceVirtual,"","","","","");
        baseService.saveObject(businessTaskDetail);
        return businessTaskDetail;
    }

    @Override
    public void updateFinishBusinessTaskDetail(BusinessTaskDetail businessTaskDetail,String msg) {
        businessTaskDetail.setState(BusinessTaskState.finish);
        businessTaskDetail.setMsg(msg);
        baseService.updateObject(businessTaskDetail);
        List<Expression> expressionList=new ArrayList<Expression>();
        expressionList.add(Expr.ne("state", BusinessTaskState.finish.getCode()));
        expressionList.add(Expr.eq("BusinessTask", businessTaskDetail.getBusinessTask()));
        Query<BusinessTaskDetail> query=baseService.createQuery(
                BusinessTaskDetail.class, expressionList);
        int count=query.findCount();
        if(count==0){
            businessTaskDetail.getBusinessTask().setState(BusinessTaskState.finish);
            businessTaskDetail.getBusinessTask().setRemark(msg);
            baseService.updateObject(businessTaskDetail.getBusinessTask());
        }
        if(businessTaskDetail.getDeviceVirtual()==null){
            return;
        }
        if(businessTaskDetail.getCmd().equals(BusinessTaskCmd.del_virtual)){
            businessTaskDetail.getDeviceVirtual().setTaskCmd(BusinessTaskCmd.del_virtual);
        }
        businessTaskDetail.getDeviceVirtual().setRemark(msg);
        businessTaskDetail.getDeviceVirtual().setTaskState(BusinessTaskState.finish);
        baseService.updateObject(businessTaskDetail.getDeviceVirtual());
        if(StringUtils.isNotBlank(businessTaskDetail.getUploadFileAddr())){
            String uploadPath=businessTaskDetail.getUploadFileAddr();
            //成功号码
            String succPath=String.format("%s%s%s",uploadPath,File.separator,"succ.txt");
            //失败号码
            String errorPath=String.format("%s%s%s",uploadPath,File.separator,"error.txt");
            //已开通号码
            String businessPath=String.format("%s%s%s",uploadPath,File.separator,"business.txt");
            List<String> succList=StrUtil.readFileByLines(succPath);
            List<String> errorList=StrUtil.readFileByLines(errorPath);
            List<String> businessList=StrUtil.readFileByLines(businessPath);
            StringBuffer succsb=new StringBuffer();
            StringBuffer errorsb=new StringBuffer();
            for(String succ:succList){
                succsb.append(succ);
                succsb.append(",");
            }
            for(String error:errorList){
                BusinessUsePhone businessUsePhone=baseService.findObject(
                        BusinessUsePhone.class, Expr.eq("phone", error));
                baseService.delObject(businessUsePhone);
                BusinessErrorPhone businessErrorPhone=baseService.findObject(
                        BusinessErrorPhone.class, Expr.eq("phone", error));
                if(businessErrorPhone==null){
                    businessErrorPhone=new BusinessErrorPhone();
                    businessErrorPhone.setPhone(error);
                    businessErrorPhone.setState(BaseState.normal);
                    baseService.saveObject(businessErrorPhone);
                }
                errorsb.append(error);
                errorsb.append(",");
            }
            for(String business:businessList){
                BusinessUsePhone businessUsePhone=baseService.findObject(
                        BusinessUsePhone.class, Expr.eq("phone", business));
                if(businessUsePhone==null){
                    businessUsePhone=new BusinessUsePhone();
                    businessUsePhone.setPhone(business);
                    businessUsePhone.setState(BaseState.normal);
                    baseService.saveObject(businessUsePhone);
                }
            }
            businessTaskDetail.setSuccPhone(succsb.toString());
            businessTaskDetail.setErrorPhone(errorsb.toString());
            businessTaskDetail.getBusinessTask().setSuccNum(Long.valueOf(succList.size()));
            businessTaskDetail.getBusinessTask().setErrorNum(Long.valueOf(errorList.size()));
            baseService.updateObject(businessTaskDetail.getBusinessTask());
        }
    }

    @Override
    public void updateRunBusinessTaskDetail(BusinessTaskDetail businessTaskDetail, int dealNum) {
        businessTaskDetail.getBusinessTask().setDealNum(
                businessTaskDetail.getBusinessTask().getDealNum()+dealNum);
        baseService.updateObject(businessTaskDetail.getBusinessTask());
    }

    @Override
    public int saveBusinessTaskFromList(DeviceVirtual deviceVirtual,BusinessTaskCmd businessTaskCmd) {
        List<Expression> expressionList=new ArrayList<Expression>();
        expressionList.add(Expr.eq("state", BusinessTaskState.wait.getCode()));
        expressionList.add(Expr.eq("cmd", businessTaskCmd.getCode()));
        expressionList.add(Expr.eq("DeviceVirtual", deviceVirtual));
        BusinessTaskDetail businessTaskDetail=baseService.findObject(
                BusinessTaskDetail.class, expressionList);
        if(businessTaskDetail!=null){
            return Constants.STATE_OPERATOR_SUCC;
        }
        BusinessTask businessTask=getBusinessTask(BusinessTaskState.wait);
        baseService.saveObject(businessTask);
        businessTaskDetail=getBusinessTaskDetail(
                businessTask,businessTaskCmd, deviceVirtual,"","","","","");
        return baseService.saveObject(businessTaskDetail);
    }


    @Override
    public int saveBusinessTaskFromAdd(BusinessGroup businessGroup,
                                       String msg,String imgAddr,String path) {
        int state= Constants.STATE_OPERATOR_LOST;
        int total=phoneService.getBusinessUsePhoneCount(businessGroup);
        if(total==0){
            return state;
        }
        int appleSendNum=80;
        BaseConfig baseConfig=configService.findObject(BaseConfigCode.apple_send_num);
        if(baseConfig!=null){
            try{
                if(StringUtils.isNotBlank(baseConfig.getValue())){
                    appleSendNum=Integer.parseInt(baseConfig.getValue());
                }
            }catch (Exception e){
                log.error("", e);
            }
        }
        BusinessTask businessTask=getBusinessTask(BusinessTaskState.init);
        baseService.saveObject(businessTask);
        Pages pages=new Pages();
        pages.setPerPageNum(appleSendNum);
        pages.setTotalNum(total);
        pages.executeCount();
        int totalNum=0;
        for(int i=0;i<pages.getAllPage();i++){
            List<BusinessUsePhone>  businessUsePhoneList= phoneService.findBusinessUsePhoneList(
                    businessGroup,i*appleSendNum,appleSendNum);
            if(businessUsePhoneList==null||businessUsePhoneList.size()==0){
                break;
            }
            StringBuffer allPhonesb=new StringBuffer();
            for(BusinessUsePhone businessUsePhone:businessUsePhoneList){
                allPhonesb.append(businessUsePhone.getPhone());
                allPhonesb.append(",");
                totalNum=totalNum+1;
            }
            BusinessTaskDetail businessTaskDetail=getBusinessTaskDetail(
                    businessTask,BusinessTaskCmd.send_batch_msg,null,
                    allPhonesb.toString().substring(0, allPhonesb.toString().length()-1),
                    msg, imgAddr, path,"");
            baseService.saveObject(businessTaskDetail);
        }
        businessTask.setTotalNum(Long.valueOf(totalNum));
        baseService.updateObject(businessTask);
        state= Constants.STATE_OPERATOR_SUCC;
        return state;
    }

    @Override
    public BusinessTaskDetail createWumaConfig(DeviceVirtual deviceVirtual) {
        BusinessTask businessTask=getBusinessTask(BusinessTaskState.run);
        baseService.saveObject(businessTask);
        BusinessWuma businessWuma=wumaService.findBusinessWuma(deviceVirtual.getVirtualMac());
        String realPath=String.format("%s%s%s",
                StrUtil.getOsResourceLoc(environment),File.separator,"task");
        File fileDir = new File(realPath);
        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }
        String dir=UUID.randomUUID().toString().replaceAll("-", "");
        realPath=realPath+File.separator+dir;
        fileDir = new File(realPath);
        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }
        StrUtil.createFile(realPath,"config.plist", businessWuma.getConfigData(),"UTF-8");
        List<String> filePathList=new ArrayList<>();
        StrUtil.cycleDirectory(new File(realPath), filePathList);
        String[] inputFileNames = new String[filePathList.size()];
        for(int i=0;i<filePathList.size();i++){
            File f=new File(filePathList.get(i));
            inputFileNames[i]=f.getName();
        }
        String zipName= ZipUtils.zip(realPath, inputFileNames, deviceVirtual.getVirtualMac());
        BusinessTaskDetail businessTaskDetail=getBusinessTaskDetail(
                businessTask,BusinessTaskCmd.replace_wuma,deviceVirtual,
                "", "", "", realPath,zipName);
        businessTaskDetail.setBusinessWuma(businessWuma);
        baseService.saveObject(businessTaskDetail);
        deviceVirtual.setTaskState(BusinessTaskState.run);
        deviceVirtual.setTaskCmd(BusinessTaskCmd.replace_wuma);
        baseService.updateObject(deviceVirtual);
        return businessTaskDetail;
    }

    @Override
    public BusinessTaskDetail createSingleMsg(DeviceVirtual deviceVirtual) {
        BusinessApple businessApple=appleService.findBusinessApple();
        if(businessApple==null){
            return null;
        }
        BusinessTask businessTask=getBusinessTask(BusinessTaskState.run);
        baseService.saveObject(businessTask);
        List<BusinessUsePhone> businessUsePhoneList=phoneService.findBusinessTestPhoneList();
        BusinessWuma businessWuma=wumaService.findBusinessWuma(deviceVirtual.getVirtualMac());
        businessWuma.setBusinessApple(businessApple);
        businessApple.setState(BusinessAppleState.used);
        baseService.updateObject(businessWuma);
        baseService.updateObject(businessApple);
        String realPath=String.format("%s%s%s",
                StrUtil.getOsResourceLoc(environment),File.separator,"task");
        File fileDir = new File(realPath);
        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }
        String dir=UUID.randomUUID().toString().replaceAll("-", "");
        realPath=realPath+File.separator+dir;
        fileDir = new File(realPath);
        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }
        StringBuffer phonesb=new StringBuffer();
        if(businessUsePhoneList!=null&&businessUsePhoneList.size()>0){
            for(BusinessUsePhone businessUsePhone:businessUsePhoneList){
                phonesb.append(businessUsePhone.getPhone());
                phonesb.append(System.getProperty("line.separator"));
            }
        }
        StrUtil.createFile(realPath,"phone.txt" ,phonesb.toString(),"UTF-8");
        StringBuffer applesb=new StringBuffer();
        applesb.append(businessApple.getAppleId());
        applesb.append(System.getProperty("line.separator"));
        applesb.append(businessApple.getApplePasswd());
        StrUtil.createFile(realPath,"apple.txt" ,applesb.toString(),"UTF-8");
        String msg=phoneService.findTestMsg();
        StrUtil.createFile(realPath,"msg.txt" ,msg,"GBK");
        List<String> filePathList=new ArrayList<>();
        StrUtil.getFiles(realPath, filePathList);
        String[] inputFileNames = new String[filePathList.size()];
        for(int i=0;i<filePathList.size();i++){
            File f=new File(filePathList.get(i));
            inputFileNames[i]=f.getName();
        }
        String zipName= ZipUtils.zip(realPath, inputFileNames, deviceVirtual.getVirtualMac());
        BusinessTaskDetail businessTaskDetail=getBusinessTaskDetail(
                businessTask,BusinessTaskCmd.send_single_msg,deviceVirtual,
                phonesb.toString(), msg, "", realPath,zipName);
        businessTaskDetail.setBusinessWuma(businessWuma);
        businessTaskDetail.setBusinessApple(businessApple);
        baseService.saveObject(businessTaskDetail);
        deviceVirtual.setTaskState(BusinessTaskState.run);
        deviceVirtual.setTaskCmd(BusinessTaskCmd.send_single_msg);
        baseService.updateObject(deviceVirtual);
        return businessTaskDetail;
    }

    @Override
    public BusinessTaskDetail createBatchMsg(DeviceVirtual deviceVirtual) {
        BusinessTaskDetail businessTaskDetail=findBusinessTaskDetailByRandom(
                BusinessTaskCmd.send_batch_msg);
        if(businessTaskDetail==null){
            return null;
        }
        StringBuffer phonesb=new StringBuffer();
        for(String phone:businessTaskDetail.getAllPhone().split(",")){
            phonesb.append(phone);
            phonesb.append(System.getProperty("line.separator"));
        }
        String realPath=businessTaskDetail.getDownFileAddr();
        StrUtil.createFile(realPath,"phone.txt" ,phonesb.toString(),"UTF-8");
        String msg=businessTaskDetail.getMsg();
        StrUtil.createFile(realPath,"msg.txt" ,msg,"GBK");
        BusinessWuma businessWuma=wumaService.findBusinessWuma(deviceVirtual.getVirtualMac());
        businessTaskDetail.setDeviceClient(deviceVirtual.getDeviceClient());
        businessTaskDetail.setDeviceVirtual(deviceVirtual);
        businessTaskDetail.setBusinessApple(businessWuma.getBusinessApple());
        businessTaskDetail.setBusinessWuma(businessWuma);
        businessTaskDetail.setState(BusinessTaskState.run);
        List<String> filePathList=new ArrayList<>();
        StrUtil.cycleDirectory(new File(realPath), filePathList);
        String[] inputFileNames = new String[filePathList.size()];
        for(int i=0;i<filePathList.size();i++){
            File f=new File(filePathList.get(i));
            inputFileNames[i]=f.getName();
        }
        businessTaskDetail.setZipFileName(
                ZipUtils.zip(realPath, inputFileNames, deviceVirtual.getVirtualMac()));
        baseService.updateObject(businessTaskDetail);
        deviceVirtual.setTaskState(BusinessTaskState.run);
        deviceVirtual.setTaskCmd(BusinessTaskCmd.send_batch_msg);
        baseService.updateObject(deviceVirtual);
        businessTaskDetail.getBusinessTask().setState(BusinessTaskState.run);
        baseService.updateObject(businessTaskDetail.getBusinessTask());
        return businessTaskDetail;
    }

    @Override
    public BusinessTaskDetail findBusinessTaskDetailByRandom(BusinessTaskCmd businessTaskCmd) {
        List<Expression> expressionList=new ArrayList<Expression>();
        expressionList.add(Expr.eq("cmd", businessTaskCmd.getCode()));
        expressionList.add(Expr.eq("state", BusinessTaskState.init.getCode()));
        if(businessTaskCmd.equals(BusinessTaskCmd.send_batch_msg)){
            expressionList.add(Expr.gt("BusinessTask.totalNum", 0));
        }
        return baseService.findObject(BusinessTaskDetail.class, expressionList,"","random()");
    }

    @Override
    public void clearBusinessTask(DeviceVirtual deviceVirtual) {
        List<Expression> expressionList=new ArrayList<Expression>();
        expressionList.add(Expr.eq("DeviceVirtual", deviceVirtual));
        List<BusinessTaskDetail> businessTaskDetailList=baseService.findList(
                BusinessTaskDetail.class, expressionList);
        if(businessTaskDetailList==null||businessTaskDetailList.size()==0){
            return;
        }
        List<BusinessTask> businessTaskList=new ArrayList<BusinessTask>();
        for(BusinessTaskDetail businessTaskDetail:businessTaskDetailList){
            businessTaskList.add(businessTaskDetail.getBusinessTask());
            baseService.delObject(businessTaskDetail);
        }
        for(BusinessTask businessTask:businessTaskList){
            baseService.delObject(businessTask);
        }
    }



    private BusinessTask getBusinessTask(
            BusinessTaskState businessTaskState){
        BusinessTask businessTask=new BusinessTask();
        businessTask.setState(businessTaskState);
        return businessTask;
    }


    private BusinessTaskDetail getBusinessTaskDetail(
            BusinessTask businessTask,BusinessTaskCmd nextBusinessTaskCmd,
            DeviceVirtual deviceVirtual, String allPhone,
            String msg,String imgAddr,String path,String zipName){
        BusinessTaskDetail businessTaskDetail=new BusinessTaskDetail();
        businessTaskDetail.setCmd(nextBusinessTaskCmd);
        businessTaskDetail.setName(nextBusinessTaskCmd.getDisplay());
        businessTaskDetail.setBusinessTask(businessTask);
        businessTaskDetail.setState(businessTask.getState());
        if(StringUtils.isNotBlank(msg)
                &&StringUtils.isNotBlank(imgAddr)){
            businessTaskDetail.setType(BusinessTaskType.text_img);
        }else if(StringUtils.isNotBlank(msg)
                &&StringUtils.isBlank(imgAddr)){
            businessTaskDetail.setType(BusinessTaskType.text);
        }else if(StringUtils.isBlank(msg)
                &&StringUtils.isNotBlank(imgAddr)){
            businessTaskDetail.setType(BusinessTaskType.img);
        }else{
            businessTaskDetail.setType(BusinessTaskType.text);
        }
        if(deviceVirtual!=null){
            businessTaskDetail.setDeviceClient(deviceVirtual.getDeviceClient());
            businessTaskDetail.setDeviceVirtual(deviceVirtual);
        }
        businessTaskDetail.setAllPhone(allPhone);
        businessTaskDetail.setImgAddr(imgAddr);
        businessTaskDetail.setMsg(msg);
        String user="";
        String passwd="";
        if(StringUtils.isNotBlank(path)){
            List<String> codeList=new ArrayList<>();
            codeList.add(BaseConfigCode.scp_user.getCode());
            codeList.add(BaseConfigCode.scp_passwd.getCode());
            List<BaseConfig> baseConfigList=configService.findList(codeList);
            for(BaseConfig baseConfig:baseConfigList){
                if(baseConfig.getCode().equals(BaseConfigCode.scp_user)){
                    user=baseConfig.getValue();
                }
                if(baseConfig.getCode().equals(BaseConfigCode.scp_passwd)){
                    passwd=baseConfig.getValue();
                }
            }
        }
        businessTaskDetail.setUsername(user);
        businessTaskDetail.setPasswd(passwd);
        businessTaskDetail.setUploadFileAddr(path);
        businessTaskDetail.setDownFileAddr(path);
        businessTaskDetail.setZipFileName(zipName);
        businessTaskDetail.setWaitPhone(businessTaskDetail.getAllPhone());
        return businessTaskDetail;
    }

}
